package pure.engine.world 
{
	import flash.geom.*;
	import pure.debug.Logger;
	import pure.engine.core.IFrameListener;
	import pure.engine.core.ns_despair;
	import pure.engine.core.ProcessManager;
	import pure.engine.entity.Entity;
	import pure.engine.entity.EntityManager;
	import pure.engine.entity.Fragment;
	import pure.engine.events.EntityMouseEvent;
	import pure.engine.events.WorldContentEvent;
	import pure.engine.events.WorldMouseEvent;
	import pure.engine.Multiple;
	import pure.utils.DesU;
	
	import pure.engine.core.ns_despair;
	use namespace ns_despair;
	
	/**
	 * 世界次元
	 * [Author] - PURE
	 * 
	 * [Process] - ① 
	 *             ② 记录可见的实体
	 *             ③ 更新实体
	 * 
	 */
public class WorldBody implements IFrameListener
{
	public function WorldBody(name:String, sortProperty:Array)
	{
		this.m_name = name;
		if (sortProperty.length)
		{
			m_sortData = m_sortData.concat(sortProperty);
		}
		ProcessManager.instance.addFrameListener(this, ProcessManager.WORLD);
	}
	

	ns_despair var m_world:WorldContent;
	
	ns_despair var m_visibleList:Array = [];
	
	ns_despair var m_numVisible:int;
	
	ns_despair var m_name:String;
	
	ns_despair var m_existed:Boolean, m_worldDirty:Boolean;
	
	ns_despair var m_sortData:Array = ['layer'];
	
	ns_despair var cachedEntityDOWN:int, cachedEntityOVER:int
		
	ns_despair var cachedMouseDown:Boolean;
	
	ns_despair var cachedFrame:int;
	
	
	
	/**
	 * 改变世界
	 */
	ns_despair function set worldContent(value:WorldContent):void 
	{
		if (m_world)
		{
			Multiple.m_notifier.dispatchEvent(new WorldContentEvent(WorldContentEvent.WORLD_WAITING, this.m_name));
			
			m_world.clearAll();
			m_world.exit();
			m_world    =  null;
			m_existed  =  false;
			
			Logger.reportMessage(this, 'Exit the world...');
		}
		
		if (value != null) 
		{
			m_world       =  value;
			m_worldDirty  =  true;
		}
	}
	
	
	/**
	 * 更新
	 */
	public function update(deltaTime:int):void
	{		
		if (m_worldDirty)
		{
			m_world.enter();
			m_existed     =  true;
			m_worldDirty  =  false;
			
			Multiple.m_notifier.dispatchEvent(new WorldContentEvent(WorldContentEvent.WORLD_CHANGE, this.m_name));
			Logger.reportMessage(this,'Enter new world : ' +DesU.getClassName(m_world));
		}
		
		if (m_existed) 
		{
			m_visibleList.length  =  0;
			m_numVisible          =  0;
			
			m_world.update(deltaTime);
			updateAliveAndRenderer(deltaTime);
		}
	}
	
	
	ns_despair function updateMouseState(type:String, M:Fragment, worldX:Number, worldY:Number, stageX:Number, stageY:Number):void
	{
		var E:Entity;
		var currID:int;
		
		currID = ( M != null ) ? M.entity.m_id : 0;
		if (currID) E = M.entity;
		
		switch(type)
		{
			case 'mouseDown':
				cachedEntityDOWN  =  currID;
				cachedMouseDown   =  true;
				// MOUSE DOWN
				if (currID) 
				{
					E.dispatchEvent(new EntityMouseEvent('mouseDown', worldX, worldY, stageX, stageY));
					//trace('[MIRROR - MOUSE DOWN] - ' + E.name + ' : ' + E.id);
				}
				
				m_world.dispatchEvent(new WorldMouseEvent('mouseDown',currID, worldX, worldY, stageX, stageY));
				//trace('[WORLD - MOUSE DOWN] - ' + worldX + ' | ' + worldY);
				break;
				
			case 'mouseUp':
				// MOUSE UP
				if (currID) 
				{
					E.dispatchEvent(new EntityMouseEvent('mouseUp', worldX, worldY, stageX, stageY));
					//trace('[MIRROR - MOUSE UP] - ' + E.name + ' : ' + E.id);
				}
				
				m_world.dispatchEvent(new WorldMouseEvent('mouseUp',currID, worldX, worldY, stageX, stageY));
				//trace('[WORLD - MOUSE UP] - ' + worldX + ' | ' + worldY);
					
				// CLICK
				if (currID == cachedEntityDOWN)
				{
					if (currID) 
					{
						E.dispatchEvent(new EntityMouseEvent('click', worldX, worldY, stageX, stageY));
						//trace('[MIRROR - CLICK] - ' + E.name + ' : ' + E.id);
					}
					
					m_world.dispatchEvent(new WorldMouseEvent('click',currID, worldX, worldY, stageX, stageY));
					//trace('[WORLD - CLICK] - ' + worldX + ' | ' + worldY);

					cachedEntityDOWN = 0;
				}

				cachedMouseDown = false;
				break;
			
			case 'mouseMove':
				// MOUSE MOVE
				if (currID)
				{	
					E.dispatchEvent(new EntityMouseEvent('mouseMove', worldX, worldY, stageX, stageY));
					//trace('[MIRROR - MOUSE MOVE] - ' + E.name + ' : ' + E.id);
				}
				
				m_world.dispatchEvent(new WorldMouseEvent('mouseMove',currID, worldX, worldY, stageX, stageY));
				//trace('[WORLD - MOUSE MOVE] - ' + worldX + ' | ' + worldY);
				
				if ( cachedEntityOVER != currID )
				{
					// MOUSE OVER
					if ( currID ) 
					{
						E.dispatchEvent(new EntityMouseEvent('mouseOver', worldX, worldY, stageX, stageY));
						//trace('[MIRROR - MOUSE OVER] - ' + E.name + ' : ' + E.id);
					}
					// 世界无需MOUSE OVER
					//else
					//{
						//trace('[WORLD - MOUSE OVER] - ' + worldX + ' | ' + worldY);
					//}
					
					// MOUSE OUT
					if ( cachedEntityOVER )
					{
						E = EntityManager.getEntityByID(cachedEntityOVER);
						if (E)
						{
							E.dispatchEvent(new EntityMouseEvent('mouseOut', worldX, worldY, stageX, stageY));
							//trace('[MOUSE OUT] - ' + E.name + ' : ' + E.id);
						}
					}
					cachedEntityOVER = currID;
				}
				break;
				
			default:
				
				break;
		}
	}
	
	
	private function updateAliveAndRenderer(deltaTime:int):void
	{	
		var E:Entity;
		var list:Vector.<Entity>
		var lenE:int, i:int;
		
		list  =  m_world.m_entityList;
		lenE  =  list.length;
		
		// 移除死亡实体
		if (!(++cachedFrame % 60))
		{
			for (i = lenE - 1; i >= 0; i--) 
			{
				E = list[i];
				if (!E.m_alive)
				{
					list.splice(i, 1);
					E.recycle();
					//continue;
				}
			
				//if (E.m_visible)
				//{
					//m_visibleList[m_numVisible++] = E;
					//E.updateRenderer(elapsedT);
				//}
			}
		}
		
		// 更新实体
		else
		{
			for (i = lenE - 1; i >= 0; i--) 
			{
				E = list[i];
				if (E.m_visible)
				{
					m_visibleList[m_numVisible++] = E;
					E.updateRenderer(deltaTime);
				}
			}
		}
	}

}

}